#include "myStateMachine.h"

#include <QFileInfo>
#include <QDebug>
#include <QSignalTransition>
#include <QMessageBox>
#include "Delay.h"

myStateMachine::myStateMachine(Widget *widget, QObject *parent)
    : QObject(parent), pUi(widget) {

}

// 初始化状态机
void myStateMachine::InitMachine()
{
    // 创建状态机
    m_machine = new QStateMachine(this);

    m_resetStatus =                 new QState(m_machine);

    m_getCsvStatus =                new QState(m_machine);
    m_initStatus =                  new QState(m_machine);
    m_topPhotoStatus =              new QState(m_machine);
    m_AFacePhotoStatus =            new QState(m_machine);
    m_BFacePhotoStatus =            new QState(m_machine);
    m_CFacePhotoStatus =            new QState(m_machine);
    m_DFacePhotoStatus =            new QState(m_machine);
    m_bottomPhotoStatus =           new QState(m_machine);

    m_cuttingStatus =               new QState(m_machine);

    m_machine->setInitialState(m_resetStatus);// 设置初始状态

    // 添加工作流程跳转
    QSignalTransition *resetStatus_To_getCsvStatus =                    m_resetStatus->addTransition(this, &myStateMachine::toNextState, m_getCsvStatus);
    QSignalTransition *getCsvStatus_To_initStatus =                     m_getCsvStatus->addTransition(this, &myStateMachine::toNextState, m_initStatus);
    QSignalTransition *initStatus_To_topPhotoStatus =                   m_initStatus->addTransition(this, &myStateMachine::toNextState, m_topPhotoStatus);
    QSignalTransition *topPhotoStatus_To_AFacePhotoStatus =             m_topPhotoStatus->addTransition(this, &myStateMachine::toNextState, m_AFacePhotoStatus);
    QSignalTransition *AFacePhotoStatus_To_BFacePhotoStatus =           m_AFacePhotoStatus->addTransition(this, &myStateMachine::toNextState, m_BFacePhotoStatus);
    QSignalTransition *BFacePhotoStatus_To_CFacePhotoStatus =           m_BFacePhotoStatus->addTransition(this, &myStateMachine::toNextState, m_CFacePhotoStatus);
    QSignalTransition *CFacePhotoStatus_To_DFacePhotoStatus =           m_CFacePhotoStatus->addTransition(this, &myStateMachine::toNextState, m_DFacePhotoStatus);
    QSignalTransition *DFacePhotoStatus_To_m_bottomFacePhotoStatus =    m_DFacePhotoStatus->addTransition(this, &myStateMachine::toNextState, m_bottomPhotoStatus);
    QSignalTransition *bottomPhotoStatus_To_cuttingStatus =             m_bottomPhotoStatus->addTransition(this, &myStateMachine::toNextState, m_cuttingStatus);
    QSignalTransition *cuttingStatus_To_initStatus =                    m_cuttingStatus->addTransition(this, &myStateMachine::toNextState, m_getCsvStatus);


    // 添加跳转

    // 初始化
    m_getCsvStatus->addTransition(this, &myStateMachine::toResetStatus, m_getCsvStatus);
    m_initStatus->addTransition(this, &myStateMachine::toResetStatus, m_getCsvStatus);

    // 复位
    m_topPhotoStatus->addTransition(this, &myStateMachine::toResetStatus, m_resetStatus);
    m_AFacePhotoStatus->addTransition(this, &myStateMachine::toResetStatus, m_resetStatus);
    m_BFacePhotoStatus->addTransition(this, &myStateMachine::toResetStatus, m_resetStatus);
    m_CFacePhotoStatus->addTransition(this, &myStateMachine::toResetStatus, m_resetStatus);
    m_DFacePhotoStatus->addTransition(this, &myStateMachine::toResetStatus, m_resetStatus);
    m_bottomPhotoStatus->addTransition(this, &myStateMachine::toResetStatus, m_resetStatus);
    m_cuttingStatus->addTransition(this, &myStateMachine::toResetStatus, m_resetStatus);

    // 初始化
//    m_initStatus->addTransition(this, &myStateMachine::toInitStatus, m_initStatus);


    // 连接定时器信号绑定槽函数
    initMachineConnectEnteredExited();

    // 初始化INI对象
    initIniManager();

    // 启动状态机
    m_machine->start();
}

void myStateMachine::initIniManager()
{
    QString iniFilePath = tr("./config/systemConfig.ini");

    m_iniSystem = new iniManager(iniFilePath, this);

    QFileInfo iniFile(iniFilePath);

    // 检查systemConfig.ini文件是否存在
    if (!iniFile.exists()) {
        qDebug() << QString(" %1 文件不存在").arg(iniFilePath);
    }

    iniFilePath = "./config/workGroupConfig.ini";

    m_iniWorkGroup = new iniManager(iniFilePath, this);

    // 检查workGroupConfig.ini文件是否存在
    if (!iniFile.exists()) {
        qDebug() << QString(" %1 文件不存在").arg(iniFilePath);
    }

}

void myStateMachine::readTimeConfig()
{
    const QString Group = "TIME";
//    m_resetTime = m_iniManager->readValue(Group, "").toInt();

    m_initTime =              m_iniSystem->readValue(Group, "initTime").toInt();
    m_topPhotoTime =          m_iniSystem->readValue(Group, "topPhotoTime").toInt();
    m_AFacePhotoTime =        m_iniSystem->readValue(Group, "AFacePhotoTime").toInt();
    m_BFacePhotoTime =        m_iniSystem->readValue(Group, "BFacePhotoTime").toInt();
    m_CFacePhotoTime =        m_iniSystem->readValue(Group, "CFacePhotoTime").toInt();
    m_DFacePhotoTime =        m_iniSystem->readValue(Group, "DFacePhotoTime").toInt();
    m_bottomPhotoTime =       m_iniSystem->readValue(Group, "bottomPhotoTime").toInt();
    m_cuttingTime =           m_iniSystem->readValue(Group, "cuttingTime").toInt();
}

void myStateMachine::showEntered(const QString &text)
{
    qDebug() << __FUNCTION__ << QString("%1 开始...").arg(text);
//    showLog(QString("%1 开始...").arg(text), LogType::Info);

    setTextColor(pUi->ui->label_devCurrState, QString("%1...").arg(text), StatusColor::Normal);
}

void myStateMachine::showExited(const QString &text)
{
    qDebug() << __FUNCTION__ << QString("%1 完成").arg(text);
//    showLog(QString("%1 完成").arg(text), LogType::Success);

    setTextColor(pUi->ui->label_devCurrState, QString("%1 完成").arg(text), StatusColor::Success);
}

void myStateMachine::initMachineConnectEnteredExited()
{
    QString resetText = tr("复位");
    connect(m_resetStatus, &QState::entered, this, [=](){
        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_resetWork);
        // 显示运行状态
        showEntered(resetText);

        pUi->ui->btn_Stop->setText("复位");
        pUi->ui->btn_Stop->setEnabled(false);
        pUi->ui->btn_switch->setEnabled(false);
        setAllBotton(false);

        do_clearAllFlag(); // 清除所有标志位

        emit sendAllLigth(0);// close All light

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_resetTime), StatusColor::Normal);

//        showLog(resetText, LogType::Warning);
        setTextColor(pUi->ui->label_devCurrState, QString("%1...").arg(resetText), StatusColor::Normal);

    });
    connect(m_resetStatus, &QState::exited, this, [=](){
        // 显示运行状态
        showExited(resetText);

//        showLog("复位完成", LogType::Success);
        setTextColor(pUi->ui->label_devCurrState, QString("%1").arg("复位完成"), StatusColor::Success);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_resetWork);

//        // 开启状态机
//        m_nextStatus = true;


        pUi->ui->btn_switch->setEnabled(true);
    });



    QString getCsvText = tr("获取任务文件1");
    connect(m_getCsvStatus, &QState::entered, this, [=](){

        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_getCsvWork);
//        // 显示运行状态
        showEntered(getCsvText);

        // 绑定定时器槽函数
        connect(&m_startTaskTimer, &QTimer::timeout, this, &myStateMachine::timerout);

        // 恢复按键
        pUi->ui->btn_Stop->setText("停止获取");
        pUi->ui->btn_Stop->setEnabled(!pUi->ui->btn_switch->isEnabled());
//        pUi->ui->btn_Stop->setEnabled(true);
        setAllBotton(true);

        do_clearAllFlag(); // 清除所有标志位

        emit sendAllLigth(0);// close All light

        // 获取时间
        readTimeConfig();

        m_csvPath = m_iniSystem->readValue("CSV", "Path").toString();

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString(), StatusColor::Normal);

        m_csvFlag = false;

//        // 隐藏提示框
//        pUi->ui->label_statusBer->hide();// 隐藏

        setTextColor(pUi->ui->label_devCurrState, "正常", StatusColor::Success);

    });

    connect(m_getCsvStatus, &QState::exited, this, [=](){

        // 累加到初始化时间
        m_initTime += m_startTask;

//        m_startTaskTimer.stop();
//        m_startTimeFlag = false;
        // 断开定时器槽函数
        disconnect(&m_startTaskTimer, &QTimer::timeout, this, &myStateMachine::timerout);

        // 显示运行状态
        showExited(getCsvText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_getCsvWork);

    });



    QString initText = tr("初始化");
    connect(m_initStatus, &QState::entered, this, [=](){

        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_initWork);
//        // 显示运行状态
        showEntered(initText);

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_initTime), StatusColor::Normal);

        if(m_csvGroup.toInt() < 2)
        {
            pUi->ui->label_statusBer->show();
            setTextColor(pUi->ui->label_statusBer, QString("没有找到 %1 绑定的工作组，请添加工作组配置!").arg(m_productClass), StatusColor::Error);
        } else {
            // 隐藏提示框
            pUi->ui->label_statusBer->hide();// 隐藏
        }

    });
    connect(m_initStatus, &QState::exited, this, [=](){

        // 禁用按键
        pUi->ui->btn_Stop->setText("复位");
//        pUi->ui->btn_Stop->setEnabled(true);
        pUi->ui->btn_Stop->setEnabled(false);
        pUi->ui->btn_switch->setEnabled(false);
        setAllBotton(false);

        // 显示运行状态
        showExited(initText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_initWork);
    });


    QString topPhotoText = tr("顶部拍照");
    connect(m_topPhotoStatus, &QState::entered, this, [=](){
        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_topPhotoWork);
        // 显示运行状态
        showEntered(topPhotoText);

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_topPhotoTime), StatusColor::Normal);

    });

    connect(m_topPhotoStatus, &QState::exited, this, [=](){
        // 显示运行状态
        showExited(topPhotoText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_topPhotoWork);

    });


    QString AFaceText = tr("A面拍照");
    connect(m_AFacePhotoStatus, &QState::entered, this, [=](){
        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_AFacePhotoWork);
        // 显示运行状态
        showEntered(AFaceText);

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_AFacePhotoTime), StatusColor::Normal);

    });
    connect(m_AFacePhotoStatus, &QState::exited, this, [=](){
        // 显示运行状态
        showExited(AFaceText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_AFacePhotoWork);

    });


    QString BFaceText = tr("B面拍照");
    connect(m_BFacePhotoStatus, &QState::entered, this, [=](){
        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_BFacePhotoWork);
        // 显示运行状态
        showEntered(BFaceText);

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_BFacePhotoTime), StatusColor::Normal);
    });
    connect(m_BFacePhotoStatus, &QState::exited, this, [=](){
        // 显示运行状态
        showExited(BFaceText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_BFacePhotoWork);

    });


    QString CFaceText = tr("C面拍照");
    connect(m_CFacePhotoStatus, &QState::entered, this, [=](){
        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_CFacePhotoWork);
        // 显示运行状态
        showEntered(CFaceText);

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_CFacePhotoTime), StatusColor::Normal);
    });
    connect(m_CFacePhotoStatus, &QState::exited, this, [=](){
        // 显示运行状态
        showExited(CFaceText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_CFacePhotoWork);

    });



    QString DFaceText = tr("D面拍照");
    connect(m_DFacePhotoStatus, &QState::entered, this, [=](){
        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_DFacePhotoWork);
        // 显示运行状态
        showEntered(DFaceText);

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_DFacePhotoTime), StatusColor::Normal);
    });
    connect(m_DFacePhotoStatus, &QState::exited, this, [=](){
        // 显示运行状态
        showExited(DFaceText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_DFacePhotoWork);
    });


    QString bottomText = tr("底部拍照");
    connect(m_bottomPhotoStatus, &QState::entered, this, [=](){
        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_bottomPhotoWork);
        // 显示运行状态
        showEntered(bottomText);

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_bottomPhotoTime), StatusColor::Normal);
    });
    connect(m_bottomPhotoStatus, &QState::exited, this, [=](){
        // 显示运行状态
        showExited(bottomText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_bottomPhotoWork);
    });


    QString cuttingText = tr("下料");
    connect(m_cuttingStatus, &QState::entered, this, [=](){
        // 连接任务信号槽
        connect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_cuttingWork);
        // 显示运行状态
        showEntered(cuttingText);

        // 显示倒计时时间
        setTextColor(pUi->ui->label_countDown, QString::number(m_cuttingTime), StatusColor::Normal);
    });
    connect(m_cuttingStatus, &QState::exited, this, [=](){

        // 显示运行状态
        showExited(cuttingText);

        // 断开任务信号槽
        disconnect(this, &myStateMachine::toStateWork, this, &myStateMachine::do_cuttingWork);
    });
}


void myStateMachine::timerout()
{
    qDebug() << "m_startTask:" << m_startTask;

    m_startTask--;

//    QString text = QString("计时：%1s / %2s").arg(m_conutTime).arg(delayTime);

//    qDebug() << text;
//    setTextColor(pUi->ui->label_countDown, QString::number(delayTime - m_conutTime), StatusColor::Normal);

    setTextColor(pUi->ui->label_countDown, QString::number(m_initTime + m_startTask), StatusColor::Normal);

    if(m_startTask<=0)
    {
        m_startTaskTimer.stop();
        m_startTimeFlag = false;
    }
}

void myStateMachine::do_getCsvWork()
{
    // 检查设备端口连接状态
    if(false == Widget::device_switch_flag)
    {
        setTextColor(pUi->ui->label_devCurrState, "设备端口连接异常", StatusColor::Error);
        return;
    }

    QString fileName = m_csvPath;

    // 获取CSV文件
    if(false == m_csvFlag)
    {
        if(!getCsvFile(fileName))
        {
            setTextColor(pUi->ui->label_devCurrState, "获取任务文件...", StatusColor::Normal);
            m_productClass.clear();
            return;
        } else {
            setTextColor(pUi->ui->label_devCurrState, "获取到任务文件", StatusColor::Success);

            qDebug() << "获取到任务文件...";
        }
    }

    // 匹配工作组
    QString productClass = m_productClass;
    QString csvGroup = m_iniWorkGroup->getGroup("productClass", productClass);

    if(csvGroup.isEmpty())
    {
        // 发送信号（提示没有匹配到工作组，跳转至新增工作组页面）
//        emit sendNewWorkGroup(m_productClass);

        // 按下【停止获取】
//        emit sendClickBtnStop();
//        qDebug() << "发送信号（提示没有匹配到工作组，跳转至新增工作组页面）";

//        return;

        // 手动模拟PLC倍速链状态
//        pUi->ui->lineEdit_chainWidth->setText(QString("宽"));

        // 获取当前倍速链宽窄
        QString chainWidth = pUi->ui->lineEdit_chainWidth->text();

//        // 检查是否存在宽窄配方
//        QString groupId;

        // 判断宽窄
        if(chainWidth == "窄")
        {
            // 调用窄配方
            csvGroup = QString("1");     // 1
        } else {
            // 调用宽配方
            csvGroup = QString("0");     // 0
        }
    }
    m_csvGroup = csvGroup;

    // 同步时间
    if(!m_startTimeString.isEmpty())
    {
        QDateTime currentTime = QDateTime::currentDateTime();
        m_startTime = QDateTime::fromString(m_startTimeString, "yyyy-MM-dd HH:mm:ss");

        if (!m_startTime.isValid()) {
            qDebug() << "无效时间";
            pUi->ui->label_statusBer->show();// 显示
            // 状态栏提示错误
            setTextColor(pUi->ui->label_statusBer, QString("格式转后（%1）无效时间").arg(m_startTask), StatusColor::Error);

            // 重新接收
            emit toResetStatus();
            return;
        }

        // 取时间查，单位为秒
        int timeDiff = currentTime.secsTo(m_startTime);

        m_startTimeString.clear();

        // 时差是否大于等于m_initTime
        if(timeDiff >= m_initTime)
        {
            m_startTask =  timeDiff - m_initTime;

//            m_startTask = m_startTask - (1 + 3);// 减去顶部拍照准备时间，顶升（1s），镜头、光源调节（3s）



            if(m_csvGroup.toInt() < 2)
            {
                pUi->ui->label_statusBer->show();
                setTextColor(pUi->ui->label_statusBer, QString("没有找到 %1 绑定的工作组，请添加工作组配置!").arg(m_productClass), StatusColor::Error);
            } else {
                // 隐藏提示框
                pUi->ui->label_statusBer->hide();// 隐藏
            }

        } else {
            pUi->ui->label_statusBer->show();// 显示
            // 状态栏提示错误
            setTextColor(pUi->ui->label_statusBer, QString("时间错误，（%1）小于初始化时间").arg(m_startTask), StatusColor::Error);

            // 重新接收
            emit toResetStatus();

            return;
        }


//        m_startTaskTimer.start(1000);

//        m_startTimeFlag = true;
    }

//    if(m_startTimeFlag == true)
//    {
//        return;
//    }
//    disconnect(&m_startTaskTimer, &QTimer::timeout, this, &myStateMachine::timerout);

    // 下个状态
    emit toNextState();
}

void myStateMachine::do_initWork()
{

    int time = m_initTime;

    // 计时
    if(conutDelay(time))
    {
        m_csvFlag = false;
        emit toNextState();
    }


    switch (m_conutTime) {
    case 1:{
        // 初始化
        setTextColor(pUi->ui->label_devCurrState, "初始化...", StatusColor::Normal);

        // 初始化焦距
        emit sendInitFocus();

        // 关灯
        emit sendAllLigth(0);
    }break;
    case 15:{
        // 更新工作组
        setTextColor(pUi->ui->label_devCurrState, "读取工作组配置...", StatusColor::Normal);
        emit sendUpdateCurrentGroup(m_csvGroup);// 更新当前选中组

//        // 开灯
//        emit sendAllLigth(100);
    }break;
    case 16:{

        // 更新工作组
        setTextColor(pUi->ui->label_devCurrState, "切换配方...", StatusColor::Normal);

        // 切换工作组
        emit sendUpdatePlcGroup(QString());


        // 复位
        setTextColor(pUi->ui->label_devCurrState, "PLC复位...", StatusColor::Normal);
        // PLC复位
        emit sendPulse(5, 1102);

        // 调整顶部拍照调焦


    }break;
    case 28:{
        // 失能停止按键
        pUi->ui->btn_Stop->setEnabled(false);

        setTextColor(pUi->ui->label_devCurrState, "PLC启动...", StatusColor::Normal);
        // PLC启动
        emit sendPulse(5, 1100);// 发送启动脉冲信号
    }break;
    default:{

    }break;
    }
}

void myStateMachine::do_topPhotoWork()
{
//    int time = ui->le_topPhotoTime->text().toInt();
    int time = m_topPhotoTime;

    if(conutDelay(time))
    {
        emit toNextState();
    }

    switch (m_conutTime) {
    case 1:{
        // 顶部拍照镜头、光源调节
        emit sendTopPhoto();

        qDebug() << "发送了 sendTopPhoto 信号.";

    }break;
    case 6:{
        // 顶部拍照 完成



    }break;
    case 0:{
        // 关灯
        emit sendTopLigth(0);

        qDebug() << "发送-->顶部拍照 finish";
        emit sendModbusRequest(0x06, 0x00, 0x02);

        // 初始化焦距
//        emit sendInitFocus();
//        emit initTopFocus();// 初始化顶部焦距
//        emit initSideFocus();// 初始化侧面焦距

//        emit sendTopFormSetData();
    }break;
    default:{

    }break;
    }

}

void myStateMachine::do_AFacePhotoWork()
{
//    int time = ui->le_AFacePhotoTime->text().toInt();
    int time = m_AFacePhotoTime;

    if(conutDelay(time))
    {
        emit toNextState();
    }

    switch (m_conutTime) {
    case 6:{
        // A面拍照 镜头、光源调节
        emit sendAFacePhoto();
        qDebug() << "发送了 sendAFacePhoto 信号.";
    }break;
    case 9:{
        // 旋转到位，开灯

    }break;
    case 12:{
        // A面拍照

    }break;
    case 0:{
        // 关灯
        emit sendSideLigth(0);
        emit sendFillLigth(0);

        qDebug() << "发送-->A面拍照 finish";
        emit sendModbusRequest(0x06, 0x01, 0x02);

        // 初始化焦距
        emit sendInitFocus();
    }break;
    default:{

    }break;
    }
}

void myStateMachine::do_BFacePhotoWork()
{
//    int time = ui->le_BFacePhotoTime->text().toInt();
    int time = m_BFacePhotoTime;

    if(conutDelay(time))
    {
        emit toNextState();
    }

    switch (m_conutTime) {
    case 6:{
        // B面拍照 镜头、光源调节
        emit sendBFacePhoto();
        qDebug() << "发送了 sendBFacePhoto 信号.";
    }break;
    case 9:{
        // 旋转到位，开灯
    }break;
    case 12:{
        // B面拍照

    }break;
    case 0:{
        // 关灯
        emit sendSideLigth(0);
        emit sendFillLigth(0);

        qDebug() << "发送-->B面拍照 finish";
        emit sendModbusRequest(0x06, 0x01, 0x02);

        // 初始化焦距
        emit sendInitFocus();
    }break;
    default:{

    }break;
    }
}

void myStateMachine::do_CFacePhotoWork()
{
//    int time = ui->le_CFacePhotoTime->text().toInt();
    int time = m_CFacePhotoTime;

    if(conutDelay(time))
    {
        emit toNextState();
    }

    switch (m_conutTime) {
    case 6:{
        // C面拍照 镜头、光源调节
        emit sendCFacePhoto();

    }break;
    case 9:{
        // 旋转到位，开灯
    }break;
    case 12:{
        // C面拍照

    }break;
    case 0:{
        // 关灯
        emit sendSideLigth(0);
        emit sendFillLigth(0);

        qDebug() << "发送-->C面拍照 finish";
        emit sendModbusRequest(0x06, 0x01, 0x02);

        // 初始化焦距
        emit sendInitFocus();
    }break;
    default:{

    }break;
    }
}

void myStateMachine::do_DFacePhotoWork()
{
//    int time = ui->le_DFacePhotoTime->text().toInt();
    int time = m_DFacePhotoTime;

    if(conutDelay(time))
    {
        emit toNextState();
    }


    switch (m_conutTime) {
    case 6:{
        // D面拍照 镜头、光源调节
        emit sendDFacePhoto();
    }break;
    case 9:{

        // 旋转到位，开灯
    }break;
    case 12:{
        // D面拍照
    }break;
    case 0:{
        // 关灯
        emit sendSideLigth(0);
        emit sendFillLigth(0);

        qDebug() << "发送-->D面拍照 finish";
        emit sendModbusRequest(0x06, 0x01, 0x02);

        // 初始化焦距
        emit sendInitFocus();
    }break;
    default:{

    }break;
    }
}

void myStateMachine::do_bottomPhotoWork()
{
//    int time = ui->le_bottomPhotoTime->text().toInt();
    int time = m_bottomPhotoTime;

    if(conutDelay(time))
    {
        emit toNextState();
    }

    switch (m_conutTime) {
    case 10:{
        // 底部拍照 镜头、光源调节
        emit sendBottomPhoto();

    }break;
    case 13:{
        // 底部拍照

    }break;
    case 0:{
        // 关灯
        emit sendBottomLigth(0);

        qDebug() << "发送-->底部拍照 finish";
        emit sendModbusRequest(0x06, 0x02, 0x02);
    }break;
    default:{

    }break;
    }
}

void myStateMachine::do_cuttingWork()
{
//    int time = ui->le_cuttingTime->text().toInt();
    int time = m_cuttingTime;

    if(conutDelay(time))
    {
        emit toNextState();
    }

    switch (m_conutTime) {
    case 1:{
        // 下料操作
        qDebug() << "下料...";
    }break;
    case 7:{
        // 发送PLC复位信号
        emit sendPulse(5, 1102);
        setTextColor(pUi->ui->label_devCurrState, "复位...", StatusColor::Success);
    }break;
    default:{

    }break;
    }
}

void myStateMachine::do_resetWork()
{
    int time = m_resetTime;

    switch (m_conutTime) {
    case 1:{
        // 第1秒时，需要做的操作

        // 发送PLC复位信号
        emit sendPulse(5, 1102);

        // 初始化焦距为740
        emit sendInitFocus();

        // 初始化所有光源亮度为100
        emit sendAllLigth(100);

//        emit setTopCamFocusLight(0, 100);
//        emit setSideCamFocusLight(0, 100, 100);

    }break;
    default:{
        // 关闭所有光源
        emit sendAllLigth(0);
    }break;
    }


    // 计时结束，跳转下一个状态
    if(conutDelay(time))
    {
        emit toNextState();
    }
}

void myStateMachine::setAllBotton(const bool &enable)
{
//    pUi->ui->btn_switch->setEnabled(enable);
//    pUi->ui->btn_Stop->setEnabled(enable);
    pUi->ui->btn_camAdjust->setEnabled(enable);
    pUi->ui->btn_systemConfig->setEnabled(enable);
    pUi->ui->btn_configWorkGroup->setEnabled(enable);
    pUi->ui->btn_LightSourceControl->setEnabled(enable);
}

void myStateMachine::do_clearAllFlag()
{
    // 清理所有标志位
    m_csvFlag = false;  // 获取到CSV文件标志位
    m_conutTime = 0;    // 计数值

    m_startTask = 0;    // 开始误差时间

    m_productCode.clear();  // 产品码
    m_productClass.clear(); // 产品类别

    m_csvGroup.clear();     // 匹配到的Group编号

    // 隐藏提示框
    pUi->ui->label_statusBer->hide();// 隐藏

    qDebug() << "所有标志位复位...";
}

bool myStateMachine::conutDelay(int delayTime)
{
//    static int conutTime = 0;

//    ++conutTime;

    m_conutTime++;

    m_conutTime %= delayTime;

    QString text = QString("计时：%1s / %2s").arg(m_conutTime).arg(delayTime);

    qDebug() << text;

//    showLog(text, LogType::Info);
    setTextColor(pUi->ui->label_countDown, QString::number(delayTime - m_conutTime), StatusColor::Normal);

    if(0 == m_conutTime)
    {
//        setTextColor(pUi->ui->label_countDown, QString(), StatusColor::Normal);
        return true;
    }



    return false;
}


bool myStateMachine::getCsvFile(const QString &csvPath)
{
    // 检查CSV文件是否存在
    if (!isExitsScvFile(csvPath))
    {
        return false;
    }

    // 读取文件
    QList<QMap<QString, QVariant>> csvDataList = readCsvFile(csvPath);
    if(csvDataList.isEmpty())
    {
//        showLog("没有读到数据", LogType::Error);
        return false;
    }

    qDebug() << "csvDataList: " << csvDataList;

    // 解析
    QString productClass;
//    QString productCode =           getDataByRowAndColumn(csvDataList, 0, QString("产品码"));
    QString materialNo =            getDataByRowAndColumn(csvDataList, 0, QString("物料编号"));
    QString workProcedureSequence = getDataByRowAndColumn(csvDataList, 0, QString("工序序号"));
    QString startTimeQString =      getDataByRowAndColumn(csvDataList, 0, QString("开始时间"));

//    qDebug() << "获取到产品码："  << productCode;
    qDebug() << "获取到物料编号："  << materialNo;
    qDebug() << "获取到工序编号："  << workProcedureSequence;
    qDebug() << "开始时间："  << startTimeQString;

    if(!materialNo.isEmpty() && !workProcedureSequence.isEmpty() )/*&& !productCode.isEmpty()*/
    {
//        qDebug() << QString("获取到任务-->产品码：%1").arg(productCode);
        productClass = materialNo + "_" + workProcedureSequence;
        qDebug() << "-------->获取到 物料编号_工序编号：" << productClass;

//        m_productCode = productCode;

        m_productClass = productClass;

        m_startTimeString = startTimeQString;

//        m_materialNo = materialNo;
//        m_workProcedureSequence = workProcedureSequence;
    } else {
        qDebug() << "-------->错误：空数据 " ;
        return false;
    }

//    showLog(QString("获取到任务-->产品码：%1").arg(productCode), LogType::Info);

    // 删除文件
    if(QFile::remove(csvPath))
    {
//        showLog(QString("CSV文件删除"), LogType::Success);

        m_csvFlag = true;

    } else {
//        showLog(QString("CSV文件删除失败！"), LogType::Error);
        return false;
    }

    return true;
}


bool myStateMachine::isExitsScvFile(const QString &csvPath)
{
    QFileInfo iniFile(csvPath);

    // 检查CSV文件是否存在
    if (!iniFile.exists())
    {
//        showLog(QString("CSV文件不存在：%1").arg(csvPath), LogType::Error);
        return false;
    }
    return true;
}

QList<QMap<QString, QVariant>> myStateMachine::readCsvFile(const QString &csvPath) {
    QList<QMap<QString, QVariant>> csvDataList;

    // 检查csv文件是否存在
    if(!isExitsScvFile(csvPath)) {
        return csvDataList;
    }

    // 读取csv文件的内容
    QString filePath = csvPath;
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "无法打开文件：" << filePath;
        return csvDataList;
    }

    QTextStream in(&file);
    QStringList headers;
    bool isHeader = true;
    while (!in.atEnd()) {
        QString line = in.readLine().trimmed(); // 去除行尾的换行符和空白字符
        if (line.isEmpty()) continue; // 跳过空行

        QStringList values = line.split(',');

        if (isHeader) {
            headers = values;
            isHeader = false;
        } else {
            QMap<QString, QVariant> rowData;
            for (int i = 0; i < headers.size(); ++i) {
                if (i < values.size()) {
                    rowData[headers.at(i)] = values.at(i);
                } else {
                    rowData[headers.at(i)] = QVariant(); // 如果数据不足，则填充空值
                }
            }
            csvDataList.append(rowData);
        }
    }
    file.close();

    return csvDataList;
}



QString myStateMachine::getDataByRowAndColumn(const QList<QMap<QString, QVariant>> &csvDataList, int row, const QString &column) {
    if (row >= 0 && row < csvDataList.size()) {
        const QMap<QString, QVariant> &rowData = csvDataList.at(row);
        if (rowData.contains(column)) {
            return rowData.value(column).toString();
        } else {
            qDebug() << "列名不存在：" << column;
        }
    } else {
        qDebug() << "行号超出范围：" << row;
    }
    return QString();
}

QMap<QString, QVariant> myStateMachine::getRowData(const QList<QMap<QString, QVariant>> &csvDataList, int row) {
    if (row >= 0 && row < csvDataList.size()) {
        return csvDataList.at(row);
    } else {
        qDebug() << "行号超出范围：" << row;
        return QMap<QString, QVariant>();
    }
}




// 获取颜色函数
QColor myStateMachine::getColor(StatusColor status) {
    return QColor(static_cast<QRgb>(status));
}

// 模板函数来设置控件的文本和颜色
template<typename T>
void myStateMachine::setTextColor(T *widget, const QString &text, StatusColor status) {
    // 空指针检查
    if (widget == nullptr) {
        qDebug() << "控件指针为NULL，空指针访问!";
        return;
    }

    try {
        // 设置文本
        widget->setText(text);

        // 设置颜色
        QPalette palette = widget->palette();

        if (std::is_same<T, QLineEdit>::value) {
            palette.setColor(QPalette::Text, getColor(status));
        } else if (std::is_same<T, QLabel>::value) {
            palette.setColor(QPalette::WindowText, getColor(status));
        } else {
            qDebug() << "不支持的控件类型!";
            return;
        }
        widget->setPalette(palette);
    } catch (const std::exception &e) {
        qDebug() << "设置文本或颜色时发生异常:" << e.what();
    } catch (...) {
        qDebug() << "设置文本或颜色时发生未知异常";
    } 
}

void myStateMachine::do_plcResetPopup()
{
    if(showMessage(QString("警告"), QString("确定要复位吗？")))
    {

        // 发送跳转复位
        emit toResetStatus();
    }
}


// 封装的函数，用于显示信息提示弹窗
bool myStateMachine::showMessage(const QString& title, const QString& message) {
    bool flag = false;

    QMessageBox msgBox;
    msgBox.setWindowTitle(title);
    msgBox.setText(message);

    // 设置按钮文本
    QPushButton *okButton = msgBox.addButton(tr("确定"), QMessageBox::AcceptRole);
    QPushButton *cancelButton = msgBox.addButton(tr("取消"), QMessageBox::RejectRole);

    // 显示消息框并等待用户交互
    msgBox.exec();

    // 根据用户选择进行处理
    if (msgBox.clickedButton() == okButton) {
        // 用户点击了确定按钮
        qDebug() << "用户点击了确定按钮";
        flag = true;
    } else if (msgBox.clickedButton() == cancelButton) {
        // 用户点击了取消按钮
        qDebug() << "用户点击了取消按钮";
        flag = false;
    }
    return flag;
}
